//package com.ews.onlineexchange.service.schedule;
//
//import java.math.BigDecimal;
//import java.util.Calendar;
//import java.util.HashMap;
//import java.util.LinkedHashMap;
//import java.util.Map;
//
//import javax.annotation.Resource;
//import javax.ejb.Schedule;
//import javax.ejb.ScheduleExpression;
//import javax.ejb.Singleton;
//import javax.ejb.Startup;
//import javax.ejb.TimerConfig;
//import javax.ejb.TimerService;
//import javax.ejb.TransactionAttribute;
//import javax.ejb.TransactionAttributeType;
//import javax.inject.Inject;
//import javax.inject.Named;
//import javax.persistence.EntityManager;
//
//import org.hibernate.CacheMode;
//import org.hibernate.FlushMode;
//import org.hibernate.Query;
//import org.hibernate.ScrollMode;
//import org.hibernate.ScrollableResults;
//import org.hibernate.Session;
//
//import com.ews.onlineexchange.model.ServiceSupplier;
//import com.ews.onlineexchange.model.approved.AnnualReviewRecord;
//import com.ews.onlineexchange.model.approved.ApprovedClass;
//import com.ews.onlineexchange.model.approved.ApprovedMatter;
//import com.ews.onlineexchange.model.approved.MatterType;
//import com.ews.onlineexchange.service.ServiceSupplierScoreCalculator;
//
///**
// * 年终考核调度器
// * @author admin
// *
// */
//@Singleton
//@Startup
//@TransactionAttribute(TransactionAttributeType.REQUIRED)
//@Named
//public class AnnualReviewTimer {
//
//	@Resource
//	TimerService timerService;
//
//	@Inject
//	EntityManager entityManager;
//
//	@Inject
//	ServiceSupplierScoreCalculator serviceSupplierScoreCalculator;
//
////	@PostConstruct
//	public void init() {
//		ScheduleExpression schedule = new ScheduleExpression();
//		timerService.createCalendarTimer(schedule, new TimerConfig("annualReviewTimer", false));
//
////		check();
//	}
//
//	private static final String DELETE_ALL_ANNUAL_REVIEW_RECORD_OF_YEAR_EQL = ""
//			+ "	DELETE			 "
//			+ "	FROM			AnnualReviewRecord arr"
//			+ "	WHERE			arr.year = :year	";
//
//	private static final String QUERY_ALL_APPROVED_MEMO_EQL = ""
//			+ "	SELECT			memo.serviceSupplier.id, memo.approvedMatter.id, SUM(memo.score) "
//			+ "	FROM			ApprovedMemo memo "
//			+ "	WHERE			memo.year = :year "
//			+ "	GROUP BY		memo.serviceSupplier.id, memo.approvedMatter.id	";
////	@Timeout
//	@Schedule(month="11", dayOfMonth="31", hour="2", minute="0", second="0", info = "annualReviewTimer", persistent = false)
//	public void run() {
//		/*
//		 * 生成年审记录
//		 */
//		generateAnnualReviewRecords();
//
//		/*
//		 * 更新中介分值
//		 */
//		calcSupplierScore();
//	}
//
//	private static final String QUERY_ALL_SUPPLIER_EQL = ""
//			+ "	SELECT			ss"
//			+ "	FROM			ServiceSupplier ss"
//			+ "	";
//
//	private void calcSupplierScore() {
//		Session session = entityManager.unwrap( Session.class );
//		Calendar now = Calendar.getInstance();
//		ScrollableResults sr = session.createQuery(QUERY_ALL_SUPPLIER_EQL).setCacheMode( CacheMode.IGNORE )
//		        .scroll( ScrollMode.FORWARD_ONLY );
//		long count = 0l;
//		while (sr.next()) {
//			ServiceSupplier _ss = (ServiceSupplier) sr.get(0);
//			BigDecimal buyerRateScore = serviceSupplierScoreCalculator.calcBuyerScore(_ss.getId());
//			BigDecimal proRateScore = serviceSupplierScoreCalculator.calcProScore(_ss.getId(), now.get(Calendar.YEAR));
//			BigDecimal annualReviewScore = serviceSupplierScoreCalculator.calcAnnualReviewScore(_ss.getId(), now.get(Calendar.YEAR));
//
//			BigDecimal sum = new BigDecimal(0);
//			sum = sum.add(buyerRateScore).add(proRateScore).add(annualReviewScore);
//
//			_ss.setScore(sum);
//			session.update(_ss);
//
//			count++;
//			if (count % 10 == 0) {
//				session.flush();
//				session.clear();
//			}
//
//			session.flush();
//		}
//	}
//
//	public void generateAnnualReviewRecords() {
//
//
//		Calendar now = Calendar.getInstance();
//
//		/*
//		 * 清除当年已经生成的年审记录，避免出现重复数据验证错误
//		 * 此功能一般不会起作用，只有在调试或修改时间这类特殊情况下可能发生。
//		 */
//		Session session = entityManager.unwrap( Session.class );
//		ScrollableResults sr = session.createQuery(DELETE_ALL_ANNUAL_REVIEW_RECORD_OF_YEAR_EQL).setParameter("year", now.get(Calendar.YEAR)).setCacheMode( CacheMode.IGNORE )
//		        .scroll( ScrollMode.FORWARD_ONLY );
//		Map<String, Map<String, BigDecimal>> tmpMap = new LinkedHashMap<String, Map<String,BigDecimal>>();
//
//		while (sr.next()) {
//			Object[] objs = sr.get();
//			String supplierId = (String) objs[0];
//			String matterId = (String) objs[1];
//			BigDecimal sumScore = (BigDecimal) objs[2];
//
//			Map<String, BigDecimal> matterMap = tmpMap.get(supplierId);
//			if (matterMap == null) {
//				matterMap = new LinkedHashMap<>();
//				tmpMap.put(supplierId, matterMap);
//			}
//			matterMap.put(matterId, sumScore);
//		}
//
//		long count = 0L;
//		for (String supplierId : tmpMap.keySet()) {
//			ServiceSupplier supplier = entityManager.find(ServiceSupplier.class, supplierId);
//			Map<ApprovedClass, BigDecimal> classScoreMap = new HashMap<ApprovedClass, BigDecimal>();
//			Map<String, BigDecimal> matterMap = tmpMap.get(supplierId);
//			for (String matterId : matterMap.keySet()) {
//				ApprovedMatter matter = entityManager.find(ApprovedMatter.class, matterId);
//				BigDecimal classScore = classScoreMap.get(matter.getApprovedClass().getId());
//				if (classScore == null) {
//					classScore = new BigDecimal(0);
//				}
//				BigDecimal finalScore = matterMap.get(matterId);
//				if (matter.getMatterType().equals(MatterType.Add))
//					classScore = classScore.add(finalScore);
//				else if (matter.getMatterType().equals(MatterType.Subtract))
//					classScore = classScore.subtract(finalScore);
//
//				classScoreMap.put(matter.getApprovedClass(), classScore);
//			}
//
//			AnnualReviewRecord arr = new AnnualReviewRecord();
//			arr.setSupplier(supplier);
//			BigDecimal supplierScore = new BigDecimal(0);
//			for (ApprovedClass clazz : classScoreMap.keySet()) {
//				BigDecimal finalScore = classScoreMap.get(clazz);
//				if (clazz.getSumScore().compareTo(finalScore.abs()) < 0) {
//					if (finalScore.compareTo(new BigDecimal(0)) < 0)
//						finalScore = clazz.getSumScore().multiply(new BigDecimal(-1));
//					else
//						finalScore = clazz.getSumScore();
//				}
//				supplierScore = supplierScore.add(finalScore);
//			}
//			arr.setSumScore(supplierScore);
//			arr.setYear(now.get(Calendar.YEAR));
//			entityManager.persist(arr);
//
//			count++;
//			if (count % 10 == 0) {
//				entityManager.flush();
//				entityManager.clear();
//			}
//		}
//
//		session.flush();
//	}
//}
